{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "7de19eeb",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pickle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "927cb437",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('./train_X.pkl' , \"rb\" ) as file :\n",
    "    train_X = pickle.load(file)\n",
    "with open('./train_y.pkl' , \"rb\" ) as file :\n",
    "    train_y = pickle.load(file)\n",
    "with open('./test_X.pkl' , \"rb\" ) as file :\n",
    "    test_X = pickle.load(file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "9364abb8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# lgb、catboost、xgb"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "6b378cb1",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import os\n",
    "import time\n",
    "import gc\n",
    "import matplotlib.pyplot as plt\n",
    "import pickle\n",
    "import lightgbm as lgb\n",
    "from sklearn.model_selection import StratifiedKFold, KFold\n",
    "from sklearn.metrics import roc_auc_score,f1_score\n",
    "from sklearn.decomposition import TruncatedSVD\n",
    "from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer\n",
    "from sklearn.preprocessing import LabelEncoder,OneHotEncoder\n",
    "from scipy import sparse\n",
    "import seaborn as sns\n",
    "from datetime import *\n",
    "from functools import reduce\n",
    "from sklearn.metrics import roc_curve\n",
    "from sklearn.model_selection import StratifiedKFold\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn import feature_selection\n",
    "import datetime\n",
    "import xgboost as xgb\n",
    "from sklearn.feature_selection import VarianceThreshold\n",
    "from catboost import CatBoostClassifier as cb\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "import optuna\n",
    "from sklearn.metrics import precision_score, recall_score,f1_score\n",
    "from lightgbm import *\n",
    "seed_list=[1993,2008,4096,1015]\n",
    "import random\n",
    "random.seed(5354)\n",
    "os.environ['PYTHONHASHSEED'] = str(5354)\n",
    "np.random.seed(5354)\n",
    "pd.set_option('display.max_info_columns', 500)\n",
    "pd.set_option('display.max_columns', 1000)\n",
    "pd.set_option('display.max_row', 300)\n",
    "pd.set_option('display.float_format', lambda x: ' %.5f' % x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "393614b5",
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.utils.class_weight import compute_class_weight"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "78c3006d",
   "metadata": {},
   "outputs": [],
   "source": [
    "def cv_model(clf, train_x, train_y, test_x, clf_name, seed=None, n_classes=None):\n",
    "    folds = 5\n",
    "    kf = StratifiedKFold(n_splits=folds, shuffle=True, random_state=seed)\n",
    "    \n",
    "    # 初始化oof和predict为二维数组（多分类）\n",
    "    oof = np.zeros((train_x.shape[0], n_classes))\n",
    "    predict = np.zeros((test_x.shape[0], n_classes))\n",
    "    df_feature_importance = pd.DataFrame()\n",
    "    cv_scores = []\n",
    "    \n",
    "    # 类别列处理\n",
    "    cols_list = train_x.columns.tolist()\n",
    "    cats_list = train_x.select_dtypes(include='category').columns\n",
    "    cats_list_idx = [i for i in range(len(cols_list)) if cols_list[i] in cats_list]\n",
    "    \n",
    "    # 类别编码处理\n",
    "    if clf_name in [\"xgb\", \"cat\"]:\n",
    "        for c in cats_list:\n",
    "            le = LabelEncoder()\n",
    "            train_x[c] = train_x[c].astype('str')\n",
    "            test_x[c] = test_x[c].astype('str')\n",
    "            lb_data = pd.concat([train_x[c], test_x[c]], axis=0)\n",
    "            le.fit(lb_data)\n",
    "            train_x[c] = le.transform(train_x[c])\n",
    "            test_x[c] = le.transform(test_x[c])\n",
    "    \n",
    "    # 处理无穷值\n",
    "    if clf_name == \"xgb\":\n",
    "        train_x.replace(np.inf, 9999999, inplace=True)\n",
    "        train_x.replace(-np.inf, -9999999, inplace=True)\n",
    "        test_x.replace(np.inf, 9999999, inplace=True)\n",
    "        test_x.replace(-np.inf, -9999999, inplace=True)\n",
    "    \n",
    "    for i, (train_index, valid_index) in enumerate(kf.split(train_x, train_y)):\n",
    "        print('************************************ {} ************************************'.format(str(i+1)))\n",
    "        trn_x, trn_y, val_x, val_y = train_x.iloc[train_index], train_y[train_index], train_x.iloc[valid_index], train_y[valid_index]\n",
    "\n",
    "        if clf_name == \"lgb\":\n",
    "            # 多分类参数设置 - 添加is_unbalance=True实现class_weight='balanced'\n",
    "            params = {\n",
    "                'boost_from_average': 'false',\n",
    "                'boost': 'gbdt',\n",
    "                'metric': 'multi_logloss',\n",
    "                'num_class': n_classes,\n",
    "                'objective': 'multiclass',\n",
    "\n",
    "                'max_depth': 7,\n",
    "                'num_leaves': 2**7 - 1,\n",
    "                'min_child_weight': 16,\n",
    "                'min_data_in_leaf': 6,\n",
    "                'min_split_gain': 0.7,\n",
    "                'bagging_fraction': 0.82,\n",
    "                'feature_fraction': 0.74,\n",
    "                'reg_lambda': 2.65,\n",
    "                'reg_alpha': 3.85,\n",
    "\n",
    "                # 'max_depth': 7,\n",
    "                # 'num_leaves': 17,\n",
    "                # 'min_child_weight': 0.08296539453158054,\n",
    "                # 'min_data_in_leaf': 44,\n",
    "                # 'min_split_gain': 0.5243160224926042,\n",
    "                # 'bagging_fraction': 0.7941482676532862,\n",
    "                # 'feature_fraction': 0.8030012678735803,\n",
    "                # 'reg_lambda': 2.817630088695515,\n",
    "                # 'reg_alpha': 0.008439149819006104,\n",
    "                # 'learning_rate': 0.022579491669713875,\n",
    "\n",
    "                # 'max_depth': 12,\n",
    "                # 'num_leaves': 204,\n",
    "                # 'min_child_weight': 0.0054307946755478296,\n",
    "                # 'min_data_in_leaf': 25,\n",
    "                # 'min_split_gain': 0.7024608133031949,\n",
    "                # 'bagging_fraction': 0.8755003708935141,\n",
    "                # 'feature_fraction': 0.9817547840791777,\n",
    "                # 'reg_lambda': 0.20490441502961498,\n",
    "                # 'reg_alpha': 0.10239533624032855,\n",
    "                # 'learning_rate': 0.0025727940056529956,\n",
    "\n",
    "                'bagging_freq': 1,\n",
    "                'seed': seed,\n",
    "                'nthread': 8,\n",
    "                'n_jobs': 8,\n",
    "                'verbose': -1,\n",
    "                'is_unbalance': True  # 添加class_weight='balanced'等效参数\n",
    "            }\n",
    "\n",
    "            \n",
    "            train_matrix = clf.Dataset(trn_x,label=trn_y)\n",
    "            valid_matrix = clf.Dataset(val_x, label=val_y)\n",
    "            callbacks = [log_evaluation(period=100), early_stopping(stopping_rounds=500)]\n",
    "            \n",
    "            model = clf.train(params, train_matrix, num_boost_round=20000, \n",
    "                             valid_sets=[train_matrix, valid_matrix], \n",
    "                             callbacks=callbacks)\n",
    "            \n",
    "            val_pred = model.predict(val_x, num_iteration=model.best_iteration)\n",
    "            test_pred = model.predict(test_x, num_iteration=model.best_iteration)\n",
    "            \n",
    "            # 特征重要性\n",
    "            df_fold_importance = pd.DataFrame()\n",
    "            df_fold_importance['feature'] = train_x.columns\n",
    "            df_fold_importance['importance'] = model.feature_importance()\n",
    "            df_fold_importance['fold'] = i + 1\n",
    "            df_feature_importance = pd.concat([df_feature_importance, df_fold_importance], axis=0)\n",
    "\n",
    "        elif clf_name == \"xgb\":\n",
    "            # 计算样本权重实现class_weight='balanced'\n",
    "            class_weights = compute_class_weight('balanced', classes=np.unique(trn_y), y=trn_y)\n",
    "            sample_weights = np.array([class_weights[i] for i in trn_y])\n",
    "            \n",
    "            # 多分类参数设置\n",
    "            params = {\n",
    "                'booster': 'gbtree',\n",
    "                'objective': 'multi:softprob',\n",
    "                'eval_metric': 'mlogloss',\n",
    "                'num_class': n_classes,\n",
    "                'gamma': 1,\n",
    "                'min_child_weight': 1.5,\n",
    "                'max_depth': 7,\n",
    "                'lambda': 10,\n",
    "                'subsample': 0.7,\n",
    "                'colsample_bytree': 0.7,\n",
    "                'colsample_bylevel': 0.7,\n",
    "                'eta': 0.05,\n",
    "                'tree_method': 'exact',\n",
    "                'seed': seed,\n",
    "                'nthread': 8\n",
    "            }\n",
    "            \n",
    "            train_matrix = clf.DMatrix(trn_x, label=trn_y, weight=sample_weights)  # 添加样本权重\n",
    "            valid_matrix = clf.DMatrix(val_x, label=val_y)\n",
    "            test_matrix = clf.DMatrix(test_x)\n",
    "            \n",
    "            watchlist = [(train_matrix, 'train'), (valid_matrix, 'eval')]\n",
    "            \n",
    "            model = clf.train(params, train_matrix, num_boost_round=20000, \n",
    "                             evals=watchlist, verbose_eval=100, \n",
    "                             early_stopping_rounds=500)\n",
    "            \n",
    "            val_pred = model.predict(valid_matrix)\n",
    "            test_pred = model.predict(test_matrix)\n",
    "            \n",
    "            # 特征重要性\n",
    "            df_fold_importance = pd.DataFrame()\n",
    "            scores = model.get_score(importance_type='gain')\n",
    "            if scores:\n",
    "                df_fold_importance['feature'] = scores.keys()\n",
    "                df_fold_importance['importance'] = scores.values()\n",
    "                df_fold_importance['fold'] = i + 1\n",
    "                df_feature_importance = pd.concat([df_feature_importance, df_fold_importance], axis=0)\n",
    "\n",
    "        elif clf_name == \"cat\":\n",
    "            # 多分类参数设置 - 添加auto_class_weights='Balanced'\n",
    "            model = clf(\n",
    "                iterations=10000,\n",
    "                random_seed=seed,\n",
    "                loss_function='MultiClass',\n",
    "                eval_metric='MultiClass',\n",
    "                learning_rate=0.01,\n",
    "                max_depth=5,\n",
    "                early_stopping_rounds=200,\n",
    "                metric_period=100,\n",
    "                l2_leaf_reg=3,\n",
    "                task_type='CPU',\n",
    "                auto_class_weights='Balanced'  # 添加class_weight='balanced'\n",
    "            )\n",
    "            \n",
    "            model.fit(trn_x, trn_y, eval_set=(val_x, val_y),\n",
    "                      use_best_model=True, cat_features=cats_list_idx,\n",
    "                      verbose=1)\n",
    "            \n",
    "            val_pred = model.predict_proba(val_x)\n",
    "            test_pred = model.predict_proba(test_x)\n",
    "            \n",
    "            # 特征重要性\n",
    "            df_fold_importance = pd.DataFrame()\n",
    "            df_fold_importance['feature'] = train_x.columns\n",
    "            df_fold_importance['importance'] = model.feature_importances_\n",
    "            df_fold_importance['fold'] = i + 1\n",
    "            df_feature_importance = pd.concat([df_feature_importance, df_fold_importance], axis=0)\n",
    "        \n",
    "        # 存储预测概率\n",
    "        oof[valid_index] = val_pred\n",
    "        predict += test_pred / folds\n",
    "        \n",
    "        # 计算macro F1\n",
    "        val_pred_labels = np.argmax(val_pred, axis=1)\n",
    "        fold_f1 = f1_score(val_y, val_pred_labels, average='macro')\n",
    "        cv_scores.append(fold_f1)\n",
    "        print('Macro F1 CV score: {:<8.5f}'.format(fold_f1))\n",
    "    \n",
    "    mean_cv_f1 = np.mean(cv_scores)\n",
    "    print(\"平均 Macro F1:::\", mean_cv_f1)\n",
    "    return oof, predict, model, df_feature_importance, mean_cv_f1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "id": "3396cf40",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "************************************ 1 ************************************\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[100]\ttraining's multi_logloss: 0.730389\tvalid_1's multi_logloss: 0.827841\n",
      "[200]\ttraining's multi_logloss: 0.721765\tvalid_1's multi_logloss: 0.828297\n",
      "[300]\ttraining's multi_logloss: 0.716535\tvalid_1's multi_logloss: 0.829015\n",
      "[400]\ttraining's multi_logloss: 0.713452\tvalid_1's multi_logloss: 0.830121\n",
      "[500]\ttraining's multi_logloss: 0.711041\tvalid_1's multi_logloss: 0.83067\n",
      "Early stopping, best iteration is:\n",
      "[97]\ttraining's multi_logloss: 0.731325\tvalid_1's multi_logloss: 0.827522\n",
      "Macro F1 CV score: 0.32511 \n",
      "************************************ 2 ************************************\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[100]\ttraining's multi_logloss: 0.7343\tvalid_1's multi_logloss: 0.813113\n",
      "[200]\ttraining's multi_logloss: 0.724872\tvalid_1's multi_logloss: 0.810863\n",
      "[300]\ttraining's multi_logloss: 0.720391\tvalid_1's multi_logloss: 0.81058\n",
      "[400]\ttraining's multi_logloss: 0.717736\tvalid_1's multi_logloss: 0.809958\n",
      "[500]\ttraining's multi_logloss: 0.714856\tvalid_1's multi_logloss: 0.811529\n",
      "[600]\ttraining's multi_logloss: 0.713136\tvalid_1's multi_logloss: 0.812101\n",
      "[700]\ttraining's multi_logloss: 0.711489\tvalid_1's multi_logloss: 0.811742\n",
      "Early stopping, best iteration is:\n",
      "[251]\ttraining's multi_logloss: 0.721915\tvalid_1's multi_logloss: 0.809852\n",
      "Macro F1 CV score: 0.34064 \n",
      "************************************ 3 ************************************\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[100]\ttraining's multi_logloss: 0.73013\tvalid_1's multi_logloss: 0.815313\n",
      "[200]\ttraining's multi_logloss: 0.720964\tvalid_1's multi_logloss: 0.813965\n",
      "[300]\ttraining's multi_logloss: 0.716145\tvalid_1's multi_logloss: 0.813842\n",
      "[400]\ttraining's multi_logloss: 0.713156\tvalid_1's multi_logloss: 0.813274\n",
      "[500]\ttraining's multi_logloss: 0.710527\tvalid_1's multi_logloss: 0.815267\n",
      "[600]\ttraining's multi_logloss: 0.709315\tvalid_1's multi_logloss: 0.814988\n",
      "[700]\ttraining's multi_logloss: 0.70798\tvalid_1's multi_logloss: 0.816102\n",
      "[800]\ttraining's multi_logloss: 0.706756\tvalid_1's multi_logloss: 0.816579\n",
      "Early stopping, best iteration is:\n",
      "[319]\ttraining's multi_logloss: 0.715617\tvalid_1's multi_logloss: 0.81302\n",
      "Macro F1 CV score: 0.38860 \n",
      "************************************ 4 ************************************\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[100]\ttraining's multi_logloss: 0.733902\tvalid_1's multi_logloss: 0.812871\n",
      "[200]\ttraining's multi_logloss: 0.723468\tvalid_1's multi_logloss: 0.812939\n",
      "[300]\ttraining's multi_logloss: 0.71933\tvalid_1's multi_logloss: 0.81374\n",
      "[400]\ttraining's multi_logloss: 0.716545\tvalid_1's multi_logloss: 0.81559\n",
      "[500]\ttraining's multi_logloss: 0.713762\tvalid_1's multi_logloss: 0.817913\n",
      "[600]\ttraining's multi_logloss: 0.711536\tvalid_1's multi_logloss: 0.818037\n",
      "Early stopping, best iteration is:\n",
      "[114]\ttraining's multi_logloss: 0.732077\tvalid_1's multi_logloss: 0.812256\n",
      "Macro F1 CV score: 0.39354 \n",
      "************************************ 5 ************************************\n",
      "Training until validation scores don't improve for 500 rounds\n",
      "[100]\ttraining's multi_logloss: 0.724389\tvalid_1's multi_logloss: 0.819249\n",
      "[200]\ttraining's multi_logloss: 0.715885\tvalid_1's multi_logloss: 0.820947\n",
      "[300]\ttraining's multi_logloss: 0.711241\tvalid_1's multi_logloss: 0.821843\n",
      "[400]\ttraining's multi_logloss: 0.707819\tvalid_1's multi_logloss: 0.822888\n",
      "[500]\ttraining's multi_logloss: 0.70537\tvalid_1's multi_logloss: 0.823341\n",
      "Early stopping, best iteration is:\n",
      "[52]\ttraining's multi_logloss: 0.739236\tvalid_1's multi_logloss: 0.817633\n",
      "Macro F1 CV score: 0.32712 \n",
      "平均 Macro F1::: 0.35500066866972013\n"
     ]
    }
   ],
   "source": [
    "# 假设原始标签是1-4\n",
    "n_classes = 4\n",
    "\n",
    "# 转换标签为0-3\n",
    "train_y_converted = train_y - 1\n",
    "\n",
    "# 调用函数\n",
    "oof_probs, test_probs, model, feat_importance, mean_f1 = cv_model(\n",
    "    lgb, train_X, train_y_converted, test_X, \"lgb\", seed=42, n_classes=n_classes\n",
    ")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "id": "f5985a23",
   "metadata": {},
   "outputs": [],
   "source": [
    "# # 假设原始标签是1-4\n",
    "# n_classes = 4\n",
    "\n",
    "# # 转换标签为0-3\n",
    "# train_y_converted = train_y - 1\n",
    "\n",
    "# # 调用函数\n",
    "# oof_probs, test_probs, model, feat_importance, mean_f1 = cv_model(\n",
    "#     xgb, train_X, train_y_converted, test_X, \"xgb\", seed=42, n_classes=n_classes\n",
    "# )\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "1b5dae02",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "默认阈值Macro F1: 0.35626\n",
      "最优阈值: [1.1058088  0.9726679  0.66576777 1.44673543]\n",
      "最优阈值Macro F1: 0.39703\n"
     ]
    }
   ],
   "source": [
    "# 1. 默认阈值预测（直接取最大概率）\n",
    "default_preds_converted = np.argmax(oof_probs, axis=1)\n",
    "default_preds = default_preds_converted + 1  # 转换回1-4范围\n",
    "default_f1 = f1_score(train_y, default_preds, average='macro')\n",
    "print(f\"默认阈值Macro F1: {default_f1:.5f}\")\n",
    "\n",
    "# 2. 最优阈值预测（通过优化）\n",
    "from sklearn.preprocessing import label_binarize\n",
    "from scipy.optimize import minimize\n",
    "\n",
    "# 优化函数\n",
    "def optimize_thresholds(thresholds):\n",
    "    adjusted_probs = oof_probs / thresholds\n",
    "    preds = np.argmax(adjusted_probs, axis=1)\n",
    "    return -f1_score(train_y_converted, preds, average='macro')\n",
    "\n",
    "# 优化阈值\n",
    "result = minimize(optimize_thresholds, np.ones(n_classes), \n",
    "                  method='Nelder-Mead', \n",
    "                  bounds=[(0.1, 10)] * n_classes)\n",
    "\n",
    "best_thresholds = result.x\n",
    "print(\"最优阈值:\", best_thresholds)\n",
    "\n",
    "# 应用最优阈值\n",
    "adjusted_probs = oof_probs / best_thresholds\n",
    "best_preds_converted = np.argmax(adjusted_probs, axis=1)\n",
    "best_preds = best_preds_converted + 1  # 转换回1-4范围\n",
    "best_f1 = f1_score(train_y, best_preds, average='macro')\n",
    "print(f\"最优阈值Macro F1: {best_f1:.5f}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "d27f4f13",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 测试集预测\n",
    "# 默认阈值预测\n",
    "test_preds_default_converted = np.argmax(test_probs, axis=1)\n",
    "test_preds_default = test_preds_default_converted + 1\n",
    "\n",
    "# 最优阈值预测\n",
    "adjusted_test_probs = test_probs / best_thresholds\n",
    "test_preds_optimized_converted = np.argmax(adjusted_test_probs, axis=1)\n",
    "test_preds_optimized = test_preds_optimized_converted + 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "id": "d2331bc9",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "默认阈值预测分布:\n",
      "4    19328\n",
      "2     3686\n",
      "1      699\n",
      "3      143\n",
      "Name: 默认预测, dtype: int64\n",
      "\n",
      "最优阈值预测分布:\n",
      "4    16726\n",
      "2     3654\n",
      "3     3010\n",
      "1      466\n",
      "Name: 优化预测, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "# 保存结果\n",
    "results = pd.DataFrame()\n",
    "results['默认预测'] = test_preds_default\n",
    "results['优化预测'] = test_preds_optimized\n",
    "\n",
    "# 输出两种结果的分布\n",
    "print(\"\\n默认阈值预测分布:\")\n",
    "print(results['默认预测'].value_counts())\n",
    "\n",
    "print(\"\\n最优阈值预测分布:\")\n",
    "print(results['优化预测'].value_counts())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "id": "e55cb321",
   "metadata": {},
   "outputs": [],
   "source": [
    "submission = pd.read_csv(\"./test.csv\")[['Id']]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "id": "8f0722d7",
   "metadata": {},
   "outputs": [],
   "source": [
    "submission['Target'] = results['默认预测']\n",
    "submission['Target'] = results['优化预测']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1b7c649a",
   "metadata": {},
   "outputs": [
    {
     "ename": "",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n",
      "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n",
      "\u001b[1;31mClick <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. \n",
      "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
     ]
    }
   ],
   "source": [
    "from datetime import datetime\n",
    "\n",
    "# 获取当前时间并格式化为月日时分秒\n",
    "current_time = datetime.now().strftime(\"%m%d_%H%M%S\")\n",
    "\n",
    "# 在文件名中添加时间信息\n",
    "filename = f'submission_{current_time}.csv'\n",
    "submission.to_csv(filename, index=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "13dbdf1b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
